#include "stdafx.h"
#include "Stack.h"
#include <STDLIB.H>



void InitStack (Stack &S)        
{          
	S.MaxSize=30;
	S.stack=(ElemType *) malloc(S.MaxSize *sizeof(ElemType));   //apply the memory dynamically
	if (!S.stack) {                             //allocating memory is unsuccessfully
		AfxMessageBox(_T("Allocating fails!"));
		return;
	}
	S.top=-1;                                    //the top of the stack
}

int EmptyStack (Stack S)         //judge whether the stack is empty
{
	return S.top == -1;
}

void Push(Stack &S, ElemType item)    //push the item into the stack
{
	if(S.top == S.MaxSize-1){    //if the stack is full
		S.stack = (ElemType *) realloc( S.stack, 2*S.MaxSize*sizeof(ElemType) ); //apply more memory
		S.MaxSize= 2*S.MaxSize;   
	}
	S.top ++;        
	S.stack[S.top ].value = item.value;
	S.stack[S.top ].x = item.x;
	S.stack[S.top ].y = item.y;
	S.stack[S.top ].z = item.z;
}

ElemType Pop(Stack &S, int *itop)              //pop the top item of the stack
{   
	ElemType temp;
	if (S.top==-1)            
	{
		*itop = -1;
		temp.value = 0;
		temp.x = -1;
		temp.y = -1;
		temp.z = -1;
		return temp;
	}
	S.top--;
	return S.stack[S.top+1];
}

ElemType Peek( Stack S )        //get the top item of the stack
{          
	if (S.top==-1)              //the stack is empty
	{
		AfxMessageBox(_T("Allocating fails!"));
		exit(1);
	}
	return S.stack[S.top];
}

void ClearStack( Stack &S )     //destroy the stack
{         
	if (S.stack)
	{
		free(S.stack);         //free the memory
		S.stack = NULL;
	}
	S.top = -1;
	S.MaxSize = 0;
}



void StackOperate(int ***ImageSrc, 
				  int i, int j, int k,
				  int row, int col, int height,
				  int ***pilabel, int iLabelvalue, Stack &t, int iSortValue)
{

	ElemType eTemp;


	if (k-1>=0 && k-1<height&&
		i-1>=0 && i-1<row&&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k-1][i-1][j-1] == iSortValue && pilabel[k-1][i-1][j-1] == 0)
		{
			eTemp.value = ImageSrc[k-1][i-1][j-1];
			eTemp.x = i-1;
			eTemp.y = j-1;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i-1][j-1] = iLabelvalue;
		}
	}

	if (k-1>=0 && k-1<height&&
		i-1>=0 && i-1<row&&
		j>=0 && j<col)
	{
		if (ImageSrc[k-1][i-1][j] == iSortValue && pilabel[k-1][i-1][j] == 0)
		{
			eTemp.value = ImageSrc[k-1][i-1][j];
			eTemp.x = i-1;
			eTemp.y = j;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i-1][j] = iLabelvalue;
		}
	}


	if (k-1>=0 && k-1<height&&
		i-1>=0 && i-1<row&&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k-1][i-1][j+1] == iSortValue && pilabel[k-1][i-1][j+1] == 0)
		{
			eTemp.value = ImageSrc[k-1][i-1][j+1];
			eTemp.x = i-1;
			eTemp.y = j+1;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i-1][j+1] = iLabelvalue;
		}
	}

	if (k-1>=0 && k-1<height&&
		i>=0 && i<row&&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k-1][i][j-1] == iSortValue && pilabel[k-1][i][j-1] == 0)
		{
			eTemp.value = ImageSrc[k-1][i][j-1];
			eTemp.x = i;
			eTemp.y = j-1;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i][j-1] = iLabelvalue;
		}
	}

	if (k-1>=0 && k-1<height&&
		i>=0 && i<row&&
		j>=0 && j<col)
	{
		if (ImageSrc[k-1][i][j] == iSortValue && pilabel[k-1][i][j] == 0)
		{
			eTemp.value = ImageSrc[k-1][i][j];
			eTemp.x = i;
			eTemp.y = j;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i][j] = iLabelvalue;
		}
	}

	if (k-1>=0 && k-1<height&&
		i>=0 && i<row&&
		j+1>=0 && j+1<col)
	{

		if (ImageSrc[k-1][i][j+1] == iSortValue && pilabel[k-1][i][j+1] == 0)
		{
			eTemp.value = ImageSrc[k-1][i][j+1];
			eTemp.x = i;
			eTemp.y = j+1;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i][j+1] = iLabelvalue;
		}
	}

	if (k-1>=0 && k-1<height&&
		i+1>=0 && i+1<row&&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k-1][i+1][j-1] == iSortValue && pilabel[k-1][i+1][j-1] == 0)
		{
			eTemp.value = ImageSrc[k-1][i+1][j+1];
			eTemp.x = i+1;
			eTemp.y = j-1;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i+1][j-1] = iLabelvalue;
		}
	}

	if (k-1>=0 && k-1<height&&
		i+1>=0 && i+1<row&&
		j>=0 && j<col)
	{
		if (ImageSrc[k-1][i+1][j] == iSortValue && pilabel[k-1][i+1][j] == 0)
		{
			eTemp.value = ImageSrc[k-1][i+1][j];
			eTemp.x = i+1;
			eTemp.y = j;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i+1][j] = iLabelvalue;
		}
	}

	if (k-1>=0 && k-1<height&&
		i+1>=0 && i+1<row&&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k-1][i+1][j+1] == iSortValue && pilabel[k-1][i+1][j+1] == 0)
		{
			eTemp.value = ImageSrc[k-1][i+1][j+1];
			eTemp.x = i+1;
			eTemp.y = j+1;
			eTemp.z = k-1;
			Push(t, eTemp);
			pilabel[k-1][i+1][j+1] = iLabelvalue;
		}
	}

	if (k>=0 && k<height&&
		i-1>=0 && i-1<row&&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k][i-1][j-1] == iSortValue && pilabel[k][i-1][j-1] == 0)
		{
			eTemp.value = ImageSrc[k][i-1][j-1];
			eTemp.x = i-1;
			eTemp.y = j-1;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i-1][j-1] = iLabelvalue;
		}
	}

	if (k>=0 && k<height&&
		i-1>=0 && i-1<row&&
		j>=0 && j<col)
	{

		if (ImageSrc[k][i-1][j] == iSortValue && pilabel[k][i-1][j] == 0)
		{
			eTemp.value = ImageSrc[k][i-1][j];
			eTemp.x = i-1;
			eTemp.y = j;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i-1][j] = iLabelvalue;
		}
	}

	if (k>=0 && k<height&&
		i-1>=0 && i-1<row&&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k][i-1][j+1] == iSortValue && pilabel[k][i-1][j+1] == 0)
		{
			eTemp.value = ImageSrc[k][i-1][j+1];
			eTemp.x = i-1;
			eTemp.y = j+1;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i-1][j+1] = iLabelvalue;
		}
	}

	if (k>=0 && k<height&&
		i>=0 && i<row&&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k][i][j-1]== iSortValue && pilabel[k][i][j-1] == 0)
		{
			eTemp.value = ImageSrc[k][i][j-1];
			eTemp.x = i;
			eTemp.y = j-1;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i][j-1] = iLabelvalue;
		}
	}

	if (k>=0 && k<height&&
		i>=0 && i<row&&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k][i][j+1] == iSortValue && pilabel[k][i][j+1] == 0)
		{
			eTemp.value = ImageSrc[k][i][j+1];
			eTemp.x = i;
			eTemp.y = j+1;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i][j+1] = iLabelvalue;
		}
	}

	if (k>=0 && k<height&&
		i+1>=0 && i+1<row &&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k][i+1][j-1] == iSortValue && pilabel[k][i+1][j-1] == 0)
		{
			eTemp.value = ImageSrc[k][i+1][j-1];
			eTemp.x = i+1;
			eTemp.y = j-1;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i+1][j-1] = iLabelvalue;
		}
	}

	if (k>=0 && k<height &&
		i+1>=0 && i+1<row &&
		j>=0 && j<col)
	{
		if (ImageSrc[k][i+1][j] == iSortValue && pilabel[k][i+1][j] == 0)
		{
			eTemp.value = ImageSrc[k][i+1][j];
			eTemp.x = i+1;
			eTemp.y = j;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i+1][j] = iLabelvalue;
		}
	}

	if (k>=0 && k<height &&
		i+1>=0 && i+1<row &&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k][i+1][j+1] == iSortValue && pilabel[k][i+1][j+1] == 0)
		{
			eTemp.value = ImageSrc[k][i+1][j+1];
			eTemp.x = i+1;
			eTemp.y = j+1;
			eTemp.z = k;
			Push(t, eTemp);
			pilabel[k][i+1][j+1] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i-1>=0 && i-1<row &&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k+1][i-1][j-1] == iSortValue && pilabel[k+1][i-1][j-1] == 0)
		{
			eTemp.value = ImageSrc[k+1][i-1][j-1];
			eTemp.x = i-1;
			eTemp.y = j-1;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i-1][j-1] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i-1>=0 && i-1<row &&
		j>=0 && j<col)
	{
		if (ImageSrc[k+1][i-1][j] == iSortValue && pilabel[k+1][i-1][j] == 0)
		{
			eTemp.value = ImageSrc[k+1][i-1][j];
			eTemp.x = i-1;
			eTemp.y = j;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i-1][j] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i-1>=0 && i-1<row &&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k+1][i-1][j+1] == iSortValue && pilabel[k+1][i-1][j+1] == 0)
		{
			eTemp.value = ImageSrc[k+1][i-1][j+1];
			eTemp.x = i-1;
			eTemp.y = j+1;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i-1][j+1] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i>=0 && i<row &&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k+1][i][j-1] == iSortValue && pilabel[k+1][i][j-1] == 0)
		{
			eTemp.value = ImageSrc[k+1][i][j-1];
			eTemp.x = i;
			eTemp.y = j-1;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i][j-1] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i>=0 && i<row &&
		j>=0 && j<col)
	{
		if (ImageSrc[k+1][i][j] == iSortValue && pilabel[k+1][i][j] == 0)
		{
			eTemp.value = ImageSrc[k+1][i][j];
			eTemp.x = i;
			eTemp.y = j;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i][j] = iLabelvalue;
		}
	}


	if (k+1>=0 && k+1<height &&
		i>=0 && i<row &&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k+1][i][j+1] == iSortValue && pilabel[k+1][i][j+1] == 0)
		{
			eTemp.value = ImageSrc[k+1][i][j+1];
			eTemp.x = i;
			eTemp.y = j+1;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i][j+1] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i+1>=0 && i+1<row &&
		j-1>=0 && j-1<col)
	{
		if (ImageSrc[k+1][i+1][j-1] == iSortValue && pilabel[k+1][i+1][j-1] == 0)
		{
			eTemp.value = ImageSrc[k+1][i+1][j-1];
			eTemp.x = i+1;
			eTemp.y = j-1;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i+1][j-1] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i+1>=0 && i+1<row &&
		j>=0 && j<col)
	{
		if (ImageSrc[k+1][i+1][j] == iSortValue && pilabel[k+1][i+1][j] == 0)
		{
			eTemp.value = ImageSrc[k+1][i+1][j];
			eTemp.x = i+1;
			eTemp.y = j;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i+1][j] = iLabelvalue;
		}
	}

	if (k+1>=0 && k+1<height &&
		i+1>=0 && i+1<row &&
		j+1>=0 && j+1<col)
	{
		if (ImageSrc[k+1][i+1][j+1] == iSortValue && pilabel[k+1][i+1][j+1] == 0)
		{
			eTemp.value = ImageSrc[k+1][i+1][j+1];
			eTemp.x = i+1;
			eTemp.y = j+1;
			eTemp.z = k+1;
			Push(t, eTemp);
			pilabel[k+1][i+1][j+1] = iLabelvalue;
		}
	}


}


void Imagelabel(int ***ImageSrc, int ***pilabel, int row, int col, int height, int *iLabelNum, int iSortValue)
{
	int i=0;
	int j =0;
	int k =0;
	
	int iLabelvalue = 0;

//	pilabel[25][392][0] = 0;
	
	for (k=0; k<height; k++)
	{
		for (i=0; i<row; i++)
		{
			for (j=0; j<col; j++)
			{

				pilabel[k][i][j] = 0;
			}

		}
	}
/*
	for (i=0; i<row; i++)
	{
		for (j=0; j<col; j++)
		{
			ImageSrc[0][i][j] = 0;
			ImageSrc[height-1][i][j] = 0;
		}
	}

	for (k=0; k<height; k++)
	{
		for (j=0; j<col; j++)
		{
			ImageSrc[k][0][j] = 0;
			ImageSrc[k][row-1][j] = 0;
		}
	}

	for (k=0; k<height; k++)
	{
		for (i=0; i<row; i++)
		{
			ImageSrc[k][i][0] = 0;
			ImageSrc[k][i][col-1] = 0;
		}
	}
*/	
	Stack t;
	InitStack(t);
	
	ElemType eTemp;
	
	int itop = 0;
	
	for (k=0; k<height; k++)
	{
		for (i=1; i<row-1; i++)
		{
			for ( j=1; j<col-1; j++)
			{

				if ((ImageSrc[k][i-1][j-1] != iSortValue) &&(ImageSrc[k][i-1][j] != iSortValue) 
					&& (ImageSrc[k][i-1][j+1] != iSortValue) && (ImageSrc[k][i][j-1] != iSortValue)
					&& (ImageSrc[k][i][j] == iSortValue && pilabel[k][i][j] == 0))
				{
					itop = 0;
					iLabelvalue ++;
					pilabel[k][i][j] = iLabelvalue; 



					StackOperate(ImageSrc, 
								 i, j, k, 
								 row, col, height,
								 pilabel, iLabelvalue, t, iSortValue);

					eTemp = Pop(t, &itop) ;
					while (itop != -1)
					{
						
						StackOperate(ImageSrc, 
									eTemp.x, eTemp.y, eTemp.z,  
									row, col, height,
									pilabel, iLabelvalue, t, iSortValue);
						eTemp = Pop(t, &itop);
					}


				}


			}
		}

	}

	*iLabelNum = iLabelvalue;

	
	ClearStack(t);
	
}